﻿namespace Deppton.Web.Tests.Controllers
{
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Security.Principal;
    using System.Web;
    using System.Web.Mvc;
    using System.Xml.Linq;
    using Deppton.Model;
    using Deppton.Model.Xml;
    using Deppton.Repositories;
    using Deppton.Web.Controllers;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Moq;

    [TestClass()]
    public class SynchronizationControllerFixture
    {
        public string TestPath
        {
            get
            {
                return Directory.GetCurrentDirectory();
            }
        }

        [TestMethod()]
        public void ShouldReturnPendingSurveysDocument()
        {
            var repository = new Mock<ISurveysRepository>();
            var username = "myuser";
            var userIdentiy = new GenericPrincipal(new GenericIdentity(username), new string[0]);
            var surveys = new List<Survey>();
            var survey1 = new Survey
            {
                Id = "survey1",
                SurveyDefinitionId = "surveyDefinition1"
            };
            var survey2 = new Survey
            {
                Id = "survey2",
                SurveyDefinitionId = "surveyDefinition1"
            };
            surveys.Add(survey1);
            surveys.Add(survey2);

            repository
                .Setup(r => r.FindPendingSurveysByUser(username))
                .Returns(surveys);

            var controller = new SynchronizationController(repository.Object);

            var result = controller.RetrievePendingSurveys(userIdentiy);

            Assert.IsNotNull(result);
            Assert.IsInstanceOfType(result, typeof(ContentResult));
            var contentString = (result as ContentResult).Content;

            var contentDocument = XDocument.Parse(contentString);

            var surveyElements = contentDocument.Root.Elements("survey");

            Assert.AreEqual(surveys.Count, surveyElements.Count());

            var parsedSurveys = surveyElements.Select(e => SurveyXmlHelper.ReadFromElement(e)).ToList();

            Assert.IsTrue(parsedSurveys.AsQueryable().Any(s => s.Id == survey1.Id));
            Assert.IsTrue(parsedSurveys.AsQueryable().Any(s => s.Id == survey2.Id));
            repository.VerifyAll();
        }

        [TestMethod]
        [DeploymentItem("survey1.xml")]
        public void ShouldSaveSurveyResult()
        {
            var repositoryObject = new Mock<ISurveysRepository>();

            var survey1Path = Path.Combine(this.TestPath, "survey1.xml");
            using (var survey1Stream = new MemoryStream(File.ReadAllBytes(survey1Path)))
            {
                var survey = SurveyXmlHelper.ReadFromElement(XDocument.Load(survey1Path).Root);

                repositoryObject.Setup(r => r.Save(It.Is<Survey>(s => s.Equals(survey))));

                var username = "myuser";
                var userIdentiy = new GenericPrincipal(new GenericIdentity(username), new string[0]);

                var fileCollectionMock = new Mock<HttpFileCollectionBase>();
                fileCollectionMock.Setup(f => f.AllKeys).Returns(new[] { "survey1" });

                var postedSurvey1Mock = new Mock<HttpPostedFileBase>();
                fileCollectionMock.Setup(f => f["survey1"]).Returns(postedSurvey1Mock.Object);
                postedSurvey1Mock.Setup(f => f.InputStream).Returns(survey1Stream);

                var controller = new SynchronizationController(repositoryObject.Object);

                controller.SetFakeControllerContext();
                Mock.Get(controller.Request).Setup(r => r.Files).Returns(fileCollectionMock.Object);

                var result = controller.Save(userIdentiy);

                Assert.IsInstanceOfType(result, typeof(EmptyResult));

                repositoryObject.VerifyAll();
            }
        }
    }
}
